package com.umpay.junit.test.xcx;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.KeyFactory;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.X509EncodedKeySpec;

import org.apache.http.Header;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.junit.Test;

import com.umfwechat.util.AesUtil;
import com.umfwechat.util.DynamicCipher;
import com.umfwechat.util.HashEncrypt;
import com.umpay.util.Base64;

import net.sf.json.JSONObject;
import sun.misc.BASE64Decoder;

/**
 * 安全层测试
 * @author xtdhwl
 *
 */
public class SafeLayerSign {

	private static String umpPriKeyPath = "pkcs8_safe_rsa_private_key.pem";
	private static String umpPubKeyPath = "safe_rsa_public_key.pem";
	private static String AES_SALT = "65bf32b4befebc9768a988ceadc1b7f5";
	private static String AES_IV = "473680038f894b5cce080e6f431e07ef";
	private static int AES_KEY_SIZE = 128;
	private static int AES_ITERATION = 1000;

	@Test
	public void testA() throws UnsupportedEncodingException, Exception {
		System.out.println("a");

		JSONObject jsonObj = new JSONObject();
		jsonObj.put("userId", "a");
		jsonObj.put("password", "123456");
		HttpPost e = e(jsonObj,"");
		Header[] allHeaders = e.getAllHeaders();
		for (Header header : allHeaders) {
			System.out.println(header.getName()+"=="+header.getValue());
		}
//		System.out.println(e.getAllHeaders());
		System.out.println(e.getEntity());
		System.out.println(e);
		System.out.println(2);
	}

	private HttpPost e(JSONObject jsonObj ,String url) throws UnsupportedEncodingException, Exception {

		HttpPost post = new HttpPost(url);

		String aesKey = random(16);
		AesUtil util = new AesUtil(AES_KEY_SIZE, AES_ITERATION);

		// 1
		String jsonStr = jsonObj.toString();
		String keyId = "dummy-keyId";
		String randomNum = random(16);
		String equInfo = "dummy-equInfo";
		String safeChick = createSafeChick();

		String jsonStrEncrypt = util.encrypt(AES_SALT, AES_IV, aesKey, jsonStr);
		String safeChickEncrypt = util.encrypt(AES_SALT, AES_IV, aesKey, safeChick);
		String randomNumEncrypt = util.encrypt(AES_SALT, AES_IV, aesKey, randomNum);
		String equInfoEncrypt = util.encrypt(AES_SALT, AES_IV, aesKey, equInfo);
		String ssfe = Base64.encode(DynamicCipher.rsaEncrypt(aesKey.getBytes("UTF-8"), loadUmpayPublicKey()));

		String data = keyId + aesKey + equInfo + safeChick + randomNum;
		String signResult = HashEncrypt.doEncrypt(data, "SHA-1", "UTF-8");

		String signResultEncrypt = util.encrypt(AES_SALT, AES_IV, aesKey, signResult);

		post.setHeader("keyId", keyId);
		post.setHeader("randomNum", randomNumEncrypt);
		post.setHeader("equInfo", equInfoEncrypt);
		post.setHeader("ssfe", ssfe);
		post.setHeader("safeChick", safeChickEncrypt);
		post.setHeader("sign", signResultEncrypt);

		JSONObject bodyJson = new JSONObject();
		bodyJson.put("secretData", jsonStrEncrypt);
		post.setEntity(new ByteArrayEntity(bodyJson.toString().getBytes("UTF-8")));
		return post;
	}

	private String random(int num) {

		// 64位数字数组
		StringBuffer sb = new StringBuffer();

		for (int i = 0; i < num; i++) {
			sb.append((int) (Math.random() * 10));
		}
		return sb.toString();
	}

	private String createSafeChick() {
		// TODO
		JSONObject json = new JSONObject();
		json.put("rpid", "12345");
		return json.toString();
	}

	public static byte[] loadUmpayPublicKey() throws Exception {
		try {
			InputStream in = DynamicCipher.class.getClassLoader().getResourceAsStream(umpPubKeyPath);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String readLine = null;
			StringBuilder sb = new StringBuilder();
			while ((readLine = br.readLine()) != null) {
				if (readLine.charAt(0) == '-') {
					continue;
				} else {
					sb.append(readLine);
					sb.append('\r');
				}
			}
			return loadPublicKey(sb.toString()).getEncoded();
		} catch (Exception e) {
			throw new Exception("公钥数据流读取错误" + e);
		}
	}

	/**
	 * 从字符串中加载公钥
	 * 
	 * @param publicKeyStr
	 *            公钥数据字符串
	 * @throws Exception
	 *             加载公钥时产生的异常
	 */
	private static RSAPublicKey loadPublicKey(String publicKeyStr) throws Exception {
		try {
			BASE64Decoder base64Decoder = new BASE64Decoder();
			byte[] buffer = base64Decoder.decodeBuffer(publicKeyStr);
			KeyFactory keyFactory = KeyFactory.getInstance("RSA");
			X509EncodedKeySpec keySpec = new X509EncodedKeySpec(buffer);
			return (RSAPublicKey) keyFactory.generatePublic(keySpec);
		} catch (Exception e) {
			throw new Exception("公钥数据内容读取错误" + e);
		}
	}
	public HttpPost sign(JSONObject jsonObj,String url) throws UnsupportedEncodingException, Exception {
		System.out.println("a");
		HttpPost e = e(jsonObj,url);
		Header[] allHeaders = e.getAllHeaders();
		for (Header header : allHeaders) {
			System.out.println(header.getName()+"=="+header.getValue());
		}
//		System.out.println(e.getAllHeaders());
		System.out.println(e.getEntity());
		System.out.println(e);
		return e;
	}
}
